﻿using System;

namespace SQLPXBase.Factory.Keys.KeyModels
{
    public class SingleValuePK<T> : PrimaryKey
        where T : struct
    {
        private T? id;

        #region Constructors

        public SingleValuePK() { }
        public SingleValuePK(T? id)
            : this()
        {
            this.id = id;
        }

        #endregion

        public override bool IsEmpty
        {
            get { return !id.HasValue; }
        }

        public override PrimaryKey DefaultValue
        {
            get { return new SingleValuePK<T>(); }
        }

        public override object GetSingleValue
        {
            get { return id.HasValue ? (object)id.Value : null; }
        }

        public override object[] GetValues
        {
            get { return id.HasValue ? new object[] { id.Value } : null; }
        }

        public override void SetValues(object[] values)
        {
            CheckValues(values);

            try
            {
                id = (T)values[0];
            }
            catch (Exception ex)
            {
                throw new PrimaryKeyException(ex.Message, ex);
            }
        }

        public override int KeyLength
        {
            get { return 1; }
        }

        public T? Value
        {
            get { return id; }
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (obj.GetType() == this.GetType())
                return obj == this;

            if (obj is T)
                return this.id.Equals((T)obj);

            return false;
        }
    }

    public class IntPK : SingleValuePK<int>
    {
        public IntPK()
        {
        }

        public IntPK(int? id)
            : base(id)
        {
        }
    }
    public class LongPK : SingleValuePK<long>
    {
        public LongPK()
        {
        }

        public LongPK(long? id)
            : base(id)
        {
        }
    }
}
